home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Beginning Mac Programming
/
Beginning Mac Programming.bin
/
Open Me for REALbasic 3
/
REALbasic 3.2
/
Example Projects
/
Reusable Classes_Code
/
User Interface
/
KeyCanvas Plugin a1
/
KeyCanvas Source
/
KeyCanvas.cpp
< prev
next >
Wrap
Text File
|
2000-01-06
|
28KB
|
1,046 lines
/*
KeyCanvas Plugin
Version: 1.0
Date: January 1, 2000 (Happy New Mille...uh, Year!)
__Contact__
author: Doug Holton
email: doug.holton@vanderbilt.edu
web: http://www.playground.ltc.vanderbilt.edu/~holtondl/basic/
__Notes__
*** This code is not very well commented. Please email me any questions you
have about any part of the source, no matter how "newbie" you think your
question is. Especially since there is virtually no documentation on
Realbasic plugin programming.
*** If you know ways to improve or extend the capabilities of this plugin,
fix bugs, or you have the CW libraries for x86 installed and can add the DLL
resource to the plugin, feel free to make any changes you like.
Please send it my way so this plugin can be updated and you will be credited.
*** The ScrollBar functions were copied from K.J. Bricknell's great Macintosh-C
tutorial at http://www.mactech.com/macintosh-c/
*** The skeleton of the source was adapted from Erich Tejkowski's MacTech
sample control plugin, and moved to Thomas Tempelmann's sample plugin CW project.
*/
#include "rb_plugin.h"
#include <Appearance.h>
#include <Processes.h>
#include <Controls.h>
#include <Quickdraw.h>
//scrollbar callback functions:
ControlActionUPP actionFunctionVertUPP;
ControlActionUPP actionFunctionHorizUPP;
Boolean gHasAppearance = false;
Boolean gHaveOpened = false;
//other user functions:
static void MyControlRect(REALcontrolInstance instance, Rect *rBounds);
static Boolean notinIDE(REALcontrolInstance instance);
static void CreateVScroll(REALcontrolInstance instance);
static void CreateHScroll(REALcontrolInstance instance);
pascal void actionFunctionVert(ControlHandle controlHdl,ControlPartCode controlPartCode);
pascal void actionFunctionHoriz(ControlHandle controlHdl,ControlPartCode controlPartCode);
void doMoveScrollBox(ControlHandle controlHdl,SInt16 scrollDistance);
//-----------------------------------------
extern struct REALcontrol myControl;
/* The events this control can call: */
REALevent myEvents[] = {
{ "MouseUp(X as Integer, Y as Integer)" }, //0
{ "KeyDown(Key as String) as Boolean"}, //1
{ "GotFocus()" }, //2
{ "LostFocus()" }, //3
{ "MouseDown(X as Integer, Y as Integer) as Boolean" }, //4
{ "Paint(g as Graphics)" }, //5
{ "MouseDrag(X as Integer, Y as Integer)" }, //6
{ "VScrollChanged()" }, //7
{ "HScrollChanged()" } //8
};
/* The properties stored in each control instance. Those which are to be accessible
by the user are declared at the REALproperty myProperties section at the bottom. */
struct myData
{
Boolean enabled;
//Boolean value;
REALpicture backdrop;
Boolean readonly;
Boolean accepttabs;
REALstring text;
Boolean havefocus;
REALgraphics graphics;
ControlHandle vscroll;
ControlHandle hscroll;
Boolean usevscroll;
Boolean usehscroll;
SInt16 vmin;
SInt16 vmax;
SInt16 vval;
SInt16 hmin;
SInt16 hmax;
SInt16 hval;
Boolean hasframe;
//private properties
Boolean invscroll;
Boolean inhscroll;
};
/* CONTROL BEHAVIOR FUNCTIONS
The following functions are called at various times by RB.
You have to declare which behavior functions to use at the
REALcontrolBehaviour myBehaviour = {...}
section at the bottom.
To access the control instance's properties in these (or any) functions,
you need to add this line.
ControlData(myControl, instance, myData, data);
You can then access a property like so:
data->havefocus=true;
*/
/* Init (constructor) function (called only once).
A good place to set the default values for your properties. */
static void myInit(REALcontrolInstance instance)
{
ControlData(myControl, instance, myData, data);
data->enabled = true;
//data->value = false;
data->backdrop = nil;
data->readonly = false;
data->accepttabs = false;
data->text=nil;
data->havefocus=false;
data->vscroll=nil;
data->hscroll=nil;
data->usevscroll=true;
data->usehscroll=true;
data->vmax=10;
data->hmax=10;
data->hasframe=true;
//internal
data->invscroll=false;
data->inhscroll=false;
}
/* Open function (called *before* the instance's open event). At this point, the
control's window has been created and is available to you. (but maybe not for 68k) */
static void myOpen(REALcontrolInstance instance)
{
//Check if AppearanceLib is available:
SInt32 feature;
if (!Gestalt(gestaltAppearanceAttr, &feature))
{
gHasAppearance = true;
}
if (notinIDE(instance)) {
ControlData(myControl, instance, myData, data);
//SysBeep(30);
if (data->usevscroll)
{
CreateVScroll(instance);
}
if (data->usehscroll)
{
CreateHScroll(instance);
}
gHaveOpened=true;
}
}
/* Close window function */
static void myClose(REALcontrolInstance instance)
{
ControlData(myControl, instance, myData, data);
//SysBeep(30);
if (notinIDE(instance))
{
if (data->usevscroll)
{
DisposeControl(data->vscroll);
data->vscroll=nil;
}
if (data->usehscroll)
{
DisposeControl(data->hscroll);
data->hscroll=nil;
}
}
data->havefocus=false;
gHaveOpened=false;
}
/* Dispose (destructor) function. Clean up memory. */
static void myDispose(REALcontrolInstance instance)
{
}
/* Called during Idle events. */
static void myIdle(REALcontrolInstance instance)
{
/*
//The code here was designed to disable the scrollbars when the
//window becomes inactive, but it does not work well.
OSErr myerr;
REALwindow win=nil;
WindowPtr winhand=nil;
ProcessSerialNumber curproc;
ProcessSerialNumber frontproc;
Boolean sameproc=false;
//Boolean refreshcontrols=false;
win=REALGetControlWindow(instance);
winhand=REALGetWindowHandle(win);
ControlData(myControl, instance, myData, data);
if (win)
{
if (data->enabled)
{
myerr=GetFrontProcess(&frontproc);
myerr=GetCurrentProcess(&curproc);
SameProcess(&frontproc,&curproc,&sameproc);
if ( (winhand != FrontWindow()) || (!sameproc) )
{
//REALSelectGraphics(REALGetControlGraphics(instance));
//disable the scrollbars...
if (data->usevscroll)
{
myerr= DeactivateControl(data->vscroll);
// SetControlMaximum(data->vscroll,GetControlMinimum(data->vscroll));
// Draw1Control (data->vscroll);
}
if (data->usehscroll)
{
myerr= DeactivateControl(data->hscroll);
// SetControlMaximum(data->hscroll,GetControlMinimum(data->hscroll));
// Draw1Control (data->hscroll);
}
data->enabled=false;
}
}
else
{
myerr=GetFrontProcess(&frontproc);
myerr=GetCurrentProcess(&curproc);
SameProcess(&frontproc,&curproc,&sameproc);
if ( (winhand == FrontWindow()) && (sameproc) )
{
//REALSelectGraphics(REALGetControlGraphics(instance));
if (data->usevscroll)
{
myerr= ActivateControl(data->vscroll);
// SetControlMaximum(data->vscroll,data->vmax);
// Draw1Control (data->vscroll);
}
if (data->usehscroll)
{
myerr= ActivateControl(data->hscroll);
// SetControlMaximum(data->hscroll,data->hmax);
// Draw1Control (data->hscroll);
}
data->enabled=true;
}
}
}
*/
}
/* GotFocus: This function will be called if you set the control to accept
the focus by setting the REALcontrolAcceptFocus flag at the REALControl
section below. It will not be called at mousedown (see how to setfocus there).
You might want to keep a data->havefocus boolean property like I am doing. */
static void myGotFocus(REALcontrolInstance instance)
{
//SysBeep(30);
ControlData(myControl, instance, myData, data);
if (!(data->havefocus))
{
//Call GotFocus Event:
void (*fp)(REALcontrolInstance instance);
fp = (void (*)(REALcontrolInstance instance)) REALGetEventInstance(instance, &myEvents[2]);
if ((fp) && (data->enabled))
{
fp(instance);
}
data->havefocus=true;
}
}
/* LostFocus called if REALcontrolAcceptFocus flag set. */
static void myLostFocus(REALcontrolInstance instance)
{
ControlData(myControl, instance, myData, data);
if (data->havefocus)
{
//Call LostFocus Event:
void (*fp)(REALcontrolInstance instance);
fp = (void (*)(REALcontrolInstance instance)) REALGetEventInstance(instance, &myEvents[3]);
if ((fp) && (data->enabled))
{
fp(instance);
}
data->havefocus=false;
}
}
/* The Paint or Refresh function. This is where you draw your control. */
static void myDraw(REALcontrolInstance instance)
{
Rect r;
Rect r2;
Rect r3;
REALgraphics g;
ControlData(myControl, instance, myData, data);
//Draw my scrollbars if necessary.
//REALSelectGraphics(REALGetControlGraphics(instance));
REALGetControlBounds(instance, &r2);
if ((data->vscroll) && (data->usevscroll) && (GetControlMaximum(data->vscroll) > GetControlMinimum(data->vscroll)))
{
Draw1Control (data->vscroll);
}
if ((data->hscroll) && (data->usehscroll) && (GetControlMaximum(data->hscroll) > GetControlMinimum(data->hscroll)))
{
Draw1Control (data->hscroll);
}
r3.left=r2.left+1;
r3.right=r2.right-1;
r3.top=r2.top+1;
r3.bottom=r2.bottom-1;
if (data->hasframe) {
if (gHasAppearance) {
//r3.left=r3.left+1;
//r3.right=r3.right-1;
//r3.top=r3.top+1;
//r3.bottom=r3.bottom-1;
DrawThemeEditTextFrame(&r3,1);
} else {
FrameRect(&r3);
}
}
//ClipRect ensure any drawing done by the control instance
// doesn't spill outside its borders.
MyControlRect(instance, &r);
g=REALGetControlGraphics(instance);
REALSelectGraphics(g);
ClipRect(&r);
if (data->backdrop)
{
if (data->hasframe)
{
r.left=r.left+1;
r.top=r.top+1;
r.bottom=r.bottom-1;
r.right=r.right-1;
}
REALDrawPicturePrimitive(data->backdrop, &r, 1); //1=transparent
}
//Call my Paint(g) Event:
void (*fp)(REALcontrolInstance instance, REALgraphics);
fp = (void (*)(REALcontrolInstance instance, REALgraphics)) REALGetEventInstance(instance, &myEvents[5]);
if ((fp) && (data->enabled))
{
fp(instance, REALGetControlGraphics(instance));
}
}
/* MouseDown - return true to allow the mousedrag and mouseup functions to be called. */
static Boolean myDoMouseDown(REALcontrolInstance instance, int x, int y, int modifiers)
{
Rect r;
Point where;
ControlData(myControl, instance, myData, data);
REALGetControlBounds(instance, &r);
//If cursor hit a scrollbar, handle that and go ahead and return true so the focus isn't set.
where.h=(short) x;
where.v=(short) y;
if ((x>r.right-16) && (data->vscroll) && (data->usevscroll) && (GetControlMaximum(data->vscroll) > GetControlMinimum(data->vscroll)))
{
data->invscroll=true;
TrackControl(data->vscroll,where,(ControlActionUPP) -1);
return true;
}
if ((y>r.bottom-16) && (data->hscroll) && (data->usehscroll) && (GetControlMaximum(data->hscroll) > GetControlMinimum(data->hscroll)))
{
data->inhscroll=true;
TrackControl(data->hscroll,where,(ControlActionUPP) -1);
return true;
}
//OK, set the focus if necessary.
MyControlRect(instance, &r);
if (!(data->havefocus))
{
//data->havefocus=true;
SetFocus(instance);
data->havefocus=true;
}
//Then call the MouseDown(x,y) Event (return true if it returns true):
Boolean (*fp)(REALcontrolInstance instance, int, int);
fp = (Boolean (*)(REALcontrolInstance instance, int, int)) REALGetEventInstance(instance, &myEvents[4]);
if ((fp) && (data->enabled))
{
return fp(instance,x-r.left,y-r.top);
}
return false;
}
/* MouseDrag function */
static void myMouseDrag(REALcontrolInstance instance, int x, int y)
{
Rect r;
//Point where;
//SInt16 myval;
ControlData(myControl, instance, myData, data);
/*
//The ScrollChanged events cannot be called while scrolling (draglib takes over)
//Keep handling the scrollbars if necessary:
where.h=(short) x;
where.v=(short) y;
if (data->invscroll)
{
TrackControl(data->vscroll,where,(ControlActionUPP) -1);
//Call VScrollChanged event if necessary:
myval = GetControlValue(data->vscroll);
if (myval != data->vval)
{
data->vval = myval;
void (*fp)(REALcontrolInstance instance);
fp = (void (*)(REALcontrolInstance instance)) REALGetEventInstance(instance, &myEvents[7]);
if (fp)
{
fp(instance);
}
}
return;
}
if (data->inhscroll)
{
TrackControl(data->hscroll,where,(ControlActionUPP) -1);
//Call HScrollChanged event if necessary:
myval = GetControlValue(data->hscroll);
if (myval != data->hval)
{
data->hval = myval;
void (*fp)(REALcontrolInstance instance);
fp = (void (*)(REALcontrolInstance instance)) REALGetEventInstance(instance, &myEvents[8]);
if (fp)
{
fp(instance);
}
}
return;
}
*/
//Call the MouseDrag event:
MyControlRect(instance, &r);
void (*fp)(REALcontrolInstance instance, int, int);
fp = (void (*)(REALcontrolInstance instance, int, int)) REALGetEventInstance(instance, &myEvents[6]);
if ((fp) && (data->enabled))
{
fp(instance,x-r.left,y-r.top);
}
}
/* MouseUp */
static void myDoMouseUp(REALcontrolInstance instance, int x, int y)
{
Rect r;
SInt16 myval;
//Stop tracking the scrollbars.
ControlData(myControl, instance, myData, data);
if (data->invscroll)
{
//Call VScrollChanged event if necessary:
myval = GetControlValue(data->vscroll);
if (myval != data->vval)
{
data->vval = myval;
void (*fp)(REALcontrolInstance instance);
fp = (void (*)(REALcontrolInstance instance)) REALGetEventInstance(instance, &myEvents[7]);
if (fp)
{
fp(instance);
}
}
data->invscroll=false;
return;
}
if (data->inhscroll)
{
//Call HScrollChanged event if necessary:
myval = GetControlValue(data->hscroll);
if (myval != data->hval)
{
data->hval = myval;
void (*fp)(REALcontrolInstance instance);
fp = (void (*)(REALcontrolInstance instance)) REALGetEventInstance(instance, &myEvents[8]);
if (fp)
{
fp(instance);
}
}
data->inhscroll=false;
return;
}
//Call the mouseup event:
MyControlRect(instance, &r);
void (*fp)(REALcontrolInstance instance, int, int);
fp = (void (*)(REALcontrolInstance instance, int, int)) REALGetEventInstance(instance, &myEvents[0]);
if ((fp) && (data->enabled))
{
fp(instance,x-r.left,y-r.top);
}
}
/* The KeyDown event. This is only called if the control has the focus, and
it has to be declared as a REALproc in the control behavior definition section. */
static Boolean myDoKeyDown(REALcontrolInstance instance, int charCode, int keyCode, int modifiers)
{
const char mychar=charCode;
REALstring thechar;
//If you don't do this the user won't be able to use the menu shortcuts.
if (modifiers & cmdKey) //bitwiseand modifiers & cmdKey
{
return false;
}
//I tried to provide the option of stopping the control from losing focus when
// the tab key is pressed, but it doesn't work.
ControlData(myControl, instance, myData, data);
if ((charCode==9) && !(data->accepttabs))
{
return false;
}
//Call the KeyDown(key) event:
thechar=REALBuildString(&mychar,1);
Boolean (*fp)(REALcontrolInstance instance, REALstring);
fp = (Boolean (*)(REALcontrolInstance instance, REALstring)) REALGetEventInstance(instance, &myEvents[1]);
if ((fp) && (data->enabled) && !(data->readonly))
{
return fp(instance, thechar);
}
return false;
}
/*
CONTROL METHODS (which are accessible by the user)
These are the custom methods that can be called from your control by the user.
See Thomas Tempelmann's example plugins for more examples of method functions.
Declare them below as REALprocs.
*/
//Graphics is actually a method, not a property. It returns the control's REALgraphics.
static REALgraphics mygraphics(REALcontrolInstance instance)
{
Rect r;
REALgraphics g;
REALGetControlBounds(instance, &r);
g=REALGetControlGraphics(instance);
REALSelectGraphics(g);
MyControlRect(instance, &r);
//This keeps any drawing to the graphics from spilling outside its borders (or
// onto the scrollbars)
ClipRect(&r);
return g;
}
/* CUSTOM GETTER & SETTER FUNCTIONS
General form of getter & setter functions:
my_property_type theGetter(REALcontrolInstance instance, my_property_type param);
void theSetter(REALcontrolInstance instance, my_property_type param, my_property_type theValue);
Remember they are called in the IDE, too.
*/
static SInt16 vvalGetter(REALcontrolInstance instance, long param)
{
ControlData(myControl, instance, myData, data);
if (notinIDE(instance))
{
return GetControlValue(data->vscroll);
} else {
return data->vval;
}
}
static SInt16 vminGetter(REALcontrolInstance instance, long param)
{
ControlData(myControl, instance, myData, data);
if (notinIDE(instance))
{
return GetControlMinimum(data->vscroll);
} else {
return data->vmin;
}
}
static SInt16 vmaxGetter(REALcontrolInstance instance, long param)
{
ControlData(myControl, instance, myData, data);
if (notinIDE(instance))
{
return GetControlMaximum(data->vscroll);
} else {
return data->vmax;
}
}
static SInt16 hvalGetter(REALcontrolInstance instance, long param)
{
ControlData(myControl, instance, myData, data);
if (notinIDE(instance))
{
return GetControlValue(data->hscroll);
} else {
return data->hval;
}
}
static SInt16 hminGetter(REALcontrolInstance instance, long param)
{
ControlData(myControl, instance, myData, data);
if (notinIDE(instance))
{
return GetControlMinimum(data->hscroll);
} else {
return data->hmin;
}
}
static SInt16 hmaxGetter(REALcontrolInstance instance, long param)
{
ControlData(myControl, instance, myData, data);
if (notinIDE(instance))
{
return GetControlMaximum(data->hscroll);
} else {
return data->hmax;
}
}
static void vvalSetter(REALcontrolInstance instance, long param, SInt16 theValue)
{
ControlData(myControl, instance, myData, data);
if (theValue == data->vval)
{return;}
data->vval=theValue;
if (notinIDE(instance))
{
SetControlValue(data->vscroll,theValue);
if (gHaveOpened)
{
//Call the VScrollChanged Event:
void (*fp)(REALcontrolInstance instance);
fp = (void (*)(REALcontrolInstance instance)) REALGetEventInstance(instance, &myEvents[7]);
if (fp)
{
fp(instance);
}
}
}
}
static void vminSetter(REALcontrolInstance instance, long param, SInt16 theValue)
{
ControlData(myControl, instance, myData, data);
if (notinIDE(instance))
{
SetControlMinimum(data->vscroll,theValue);
}
data->vmin=theValue;
}
static void vmaxSetter(REALcontrolInstance instance, long param, SInt16 theValue)
{
ControlData(myControl, instance, myData, data);
if (notinIDE(instance))
{
SetControlMaximum(data->vscroll,theValue);
}
data->vmax=theValue;
}
static void hvalSetter(REALcontrolInstance instance, long param, SInt16 theValue)
{
ControlData(myControl, instance, myData, data);
if (theValue == data->hval)
{return;}
data->hval=theValue;
if (notinIDE(instance))
{
SetControlValue(data->hscroll,theValue);
if (gHaveOpened)
{
//Call the HScrollChanged event:
void (*fp)(REALcontrolInstance instance);
fp = (void (*)(REALcontrolInstance instance)) REALGetEventInstance(instance, &myEvents[8]);
if (fp)
{
fp(instance);
}
}
}
}
static void hminSetter(REALcontrolInstance instance, long param, SInt16 theValue)
{
ControlData(myControl, instance, myData, data);
if (notinIDE(instance))
{
SetControlMinimum(data->hscroll,theValue);
}
data->hmin=theValue;
}
static void hmaxSetter(REALcontrolInstance instance, long param, SInt16 theValue)
{
ControlData(myControl, instance, myData, data);
if (notinIDE(instance))
{
SetControlMaximum(data->hscroll,theValue);
}
data->hmax=theValue;
}
/*
CONTROL DECLARATIONS
These are needed in every plugin control source code. Declare which properties and
methods are accessible by the user (and how they are accessed). Declare the control
behavior and structure.
*/
REALproperty myProperties[] = {
//{"Appearance", "Enabled", "Boolean", REALpropInvalidate, REALstandardGetter, REALstandardSetter, FieldOffset(myData, enabled)},
//{"Appearance", "Value", "Boolean", REALpropInvalidate,REALstandardGetter, REALstandardSetter, FieldOffset(myData, value)},
{"Appearance", "Backdrop", "Picture", REALpropInvalidate, REALstandardGetter, REALstandardSetter, FieldOffset(myData, backdrop)},
{"Appearance", "ReadOnly", "Boolean", REALpropInvalidate, REALstandardGetter, REALstandardSetter, FieldOffset(myData, readonly)},
{"Appearance", "AcceptTabs", "Boolean", REALpropInvalidate, REALstandardGetter, REALstandardSetter, FieldOffset(myData, accepttabs)},
{"Appearance", "Text", "String", REALpropInvalidate, REALstandardGetter, REALstandardSetter, FieldOffset(myData, text)},
{"Appearance", "HaveFocus", "Boolean", REALpropRuntimeOnly, REALstandardGetter, REALstandardSetter, FieldOffset(myData, havefocus)},
{"Appearance", "HasFrame", "Boolean", REALpropInvalidate, REALstandardGetter, REALstandardSetter, FieldOffset(myData, hasframe)},
// {"VerticalScrollBar", "VScrollHandle", "Integer", REALpropRuntimeOnly, REALstandardGetter, nil, FieldOffset(myData, vscroll)},
{"VerticalScrollBar", "UseVScrollBar", "Boolean", REALpropInvalidate, REALstandardGetter, REALstandardSetter, FieldOffset(myData, usevscroll)},
{"VerticalScrollBar", "VMinimum", "Integer", REALpropInvalidate, (REALproc) vminGetter, (REALproc) vminSetter, FieldOffset(myData, vmin)},
{"VerticalScrollBar", "VMaximum", "Integer", REALpropInvalidate, (REALproc) vmaxGetter, (REALproc) vmaxSetter, FieldOffset(myData, vmax)},
{"VerticalScrollBar", "VValue", "Integer", REALpropInvalidate, (REALproc) vvalGetter, (REALproc) vvalSetter, FieldOffset(myData, vval)},
// {"HorizontalScrollBar", "HScrollHandle", "Integer", REALpropRuntimeOnly, REALstandardGetter, nil, FieldOffset(myData, hscroll)},
{"HorizontalScrollBar", "UseHScrollBar", "Boolean", REALpropInvalidate, REALstandardGetter, REALstandardSetter, FieldOffset(myData, usehscroll)},
{"HorizontalScrollBar", "HMinimum", "Integer", REALpropInvalidate, (REALproc) hminGetter, (REALproc) hminSetter, FieldOffset(myData, hmin)},
{"HorizontalScrollBar", "HMaximum", "Integer", REALpropInvalidate, (REALproc) hmaxGetter, (REALproc) hmaxSetter, FieldOffset(myData, hmax)},
{"HorizontalScrollBar", "HValue", "Integer", REALpropInvalidate, (REALproc) hvalGetter, (REALproc) hvalSetter, FieldOffset(myData, hval)}
};
REALmethodDefinition myMethods[] = {
{ (REALproc) mygraphics, REALnoImplementation, "Graphics() as Graphics"}
};
REALcontrolBehaviour myBehaviour = {
myInit, //the init function
nil, //myDispose, //the dispose function goes here
myDraw, //the redraw function
myDoMouseDown,
myMouseDrag,
myDoMouseUp,
myGotFocus, //gainedfocus
myLostFocus, //lostfocus
(REALproc) myDoKeyDown, //keydown
myOpen, //open
myClose, //close
nil //myIdle //idle
};
REALcontrol myControl = {
kCurrentREALControlVersion,
"KeyCanvas", //The default name of your control in the IDE
sizeof(myData),
REALenabledControl | REALcontrolAcceptFocus | REALcontrolFocusRing ,
/*
##define REALcontrolAcceptFocus 1
##define REALcontrolFocusRing 2
##define REALinvisibleControl 4
##define REALopaqueControl 8
##define REALenabledControl 16
*/
128,129, //Resource numbers for the pressed and unpressed pictures to use in the IDE toolbar
150,150, //default size of control when you drop it onto a window in the IDE
myProperties,
sizeof(myProperties) / sizeof(REALproperty),
myMethods,
sizeof(myMethods) / sizeof(REALmethodDefinition),
myEvents,
sizeof(myEvents) / sizeof(REALevent),
&myBehaviour
};
void PluginEntry(void)
{
REALRegisterControl(&myControl);
}
/* _________________________CUSTOM FUNCTIONS_______________________________ */
//This function shrinks the control rectangle if scrollbars are being used.
static void MyControlRect (REALcontrolInstance instance, Rect *rBounds)
{
ControlData(myControl, instance, myData, data);
REALGetControlBounds(instance, rBounds);
if ((data->vscroll) && (data->usevscroll) && (data->vmax > data->vmin))
{
rBounds->right=rBounds->right-16;
}
if ((data->hscroll) && (data->usehscroll) && (data->hmax > data->hmin))
{
rBounds->bottom=rBounds->bottom-16;
}
if (data->hasframe)
{
rBounds->top=rBounds->top+1;
rBounds->left=rBounds->left+1;
}
}
static Boolean notinIDE(REALcontrolInstance instance)
{
REALwindow win=nil;
WindowPtr winhand=nil;
win=REALGetControlWindow(instance);
if (win)
{
return true;
}
return false;
}
static void CreateVScroll(REALcontrolInstance instance)
{
Rect r;
REALwindow win=nil;
WindowPtr winhand=nil;
win=REALGetControlWindow(instance);
winhand=REALGetWindowHandle(win);
if (!win)
{return;}
ControlData(myControl, instance, myData, data);
REALGetControlBounds(instance, &r);
r.left=r.right-16;
//scrollBarProc=16 (standard scrollbar)
//kControlScrollBarProc=384 (appearance)
//kControlScrollBarLiveProc=386 (live scrollbar)
if (gHasAppearance) {
data->vscroll=NewControl(winhand,&r,"\p",true,data->vval,data->vmin,data->vmax,kControlScrollBarProc,0L);
} else {
data->vscroll=NewControl(winhand,&r,"\p",true,data->vval,data->vmin,data->vmax,scrollBarProc,0L);
}
actionFunctionVertUPP = NewControlActionProc((ProcPtr) actionFunctionVert);
SetControlAction(data->vscroll,actionFunctionVertUPP);
}
static void CreateHScroll(REALcontrolInstance instance)
{
Rect r;
REALwindow win=nil;
WindowPtr winhand=nil;
win=REALGetControlWindow(instance);
winhand=REALGetWindowHandle(win);
if (!win)
{return;}
ControlData(myControl, instance, myData, data);
REALGetControlBounds(instance, &r);
r.top=r.bottom-16;
if (data->usevscroll)
{
r.right=r.right-16;
}
//scrollBarProc=16 (standard scrollbar)
//kControlScrollBarProc=384 (appearance)
//kControlScrollBarLiveProc=386 (live scrollbar)
if (gHasAppearance) {
data->hscroll=NewControl(winhand,&r,"\p",true,data->hval,data->hmin,data->hmax,kControlScrollBarProc,0L);
} else {
data->hscroll=NewControl(winhand,&r,"\p",true,data->hval,data->hmin,data->hmax,scrollBarProc,0L);
}
actionFunctionHorizUPP = NewControlActionProc((ProcPtr) actionFunctionHoriz);
SetControlAction(data->hscroll,actionFunctionHorizUPP);
}
/*
ScrollBar callback functions (largely adapted from the Macintosh-C tutorial)
*/
/* This is the vertical scrollbar callback function: */
pascal void actionFunctionVert(ControlHandle controlHdl,ControlPartCode controlPartCode)
{
SInt16 scrollDistance, controlValue;
if(controlPartCode != kControlIndicatorPart)
{
switch(controlPartCode)
{
case kControlUpButtonPart:
case kControlDownButtonPart:
scrollDistance = 2;
break;
case kControlPageUpPart:
case kControlPageDownPart:
scrollDistance = 30;
break;
}
if((controlPartCode == kControlDownButtonPart) ||
(controlPartCode == kControlPageDownPart))
scrollDistance = -scrollDistance;
controlValue = GetControlValue(controlHdl);
if(((controlValue == GetControlMaximum(controlHdl)) && scrollDistance < 0) ||
((controlValue == GetControlMinimum(controlHdl)) && scrollDistance > 0))
return;
doMoveScrollBox(controlHdl,scrollDistance);
}
}
/* This is the horizontal scrollbar callback function: */
pascal void actionFunctionHoriz(ControlHandle controlHdl, ControlPartCode controlPartCode)
{
SInt16 scrollDistance, controlValue;
if(controlPartCode != kControlIndicatorPart)
{
switch(controlPartCode)
{
case kControlUpButtonPart:
case kControlDownButtonPart:
scrollDistance = 2;
break;
case kControlPageUpPart:
case kControlPageDownPart:
scrollDistance = 30;
break;
}
if((controlPartCode == kControlDownButtonPart) ||
(controlPartCode == kControlPageDownPart))
scrollDistance = -scrollDistance;
controlValue = GetControlValue(controlHdl);
if(((controlValue == GetControlMaximum(controlHdl)) && scrollDistance < 0) ||
((controlValue == GetControlMinimum(controlHdl)) && scrollDistance > 0))
return;
doMoveScrollBox(controlHdl,scrollDistance);
}
}
void doMoveScrollBox(ControlHandle controlHdl,SInt16 scrollDistance)
{
SInt16 oldControlValue, controlValue, controlMax;
oldControlValue = GetControlValue(controlHdl);
controlMax = GetControlMaximum(controlHdl);
controlValue = oldControlValue - scrollDistance;
if(controlValue < 0)
controlValue = 0;
else if(controlValue > controlMax)
controlValue = controlMax;
SetControlValue(controlHdl,controlValue);
}